package test
{
	import com.adobe.utils.AGALMiniAssembler;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.display.Stage3D;
	import flash.display3D.Context3D;
	import flash.display3D.Context3DProgramType;
	import flash.display3D.Context3DTextureFormat;
	import flash.display3D.Context3DVertexBufferFormat;
	import flash.display3D.IndexBuffer3D;
	import flash.display3D.Program3D;
	import flash.display3D.VertexBuffer3D;
	import flash.display3D.textures.Texture;
	import flash.events.Event;
	import flash.geom.Matrix3D;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.geom.Vector3D;
	import flash.utils.getTimer;
	
	import ricky.scene.Camera;
	
	public class stage3dMaplayer extends Sprite
	{
		public function stage3dMaplayer()
		{
			super();
			var e:Event
			this.addEventListener(Event.ADDED_TO_STAGE,init);
		}
		
		/** 变换矩阵*/
		public function get matrix3D():Matrix3D
		{
			return _camerMatrix3D;
		}

		private function init(e:Event):void
		{
			var stage3D:Stage3D=this.stage.stage3Ds[0];
			if(stage3D)
			{
				stage3D.addEventListener(Event.CONTEXT3D_CREATE,CREATE);
				stage3D.requestContext3D();
				stageWidth=this.stage.stageWidth;
				stageHeight=this.stage.stageHeight;
			}
		}
		private var stageWidth:Number,stageHeight:Number;
		private function CREATE(e:Event):void
		{
			_context3d=Stage3D(e.target).context3D;
			_context3d.configureBackBuffer(stageWidth,stageHeight,2);
			_context3d.enableErrorChecking=true;
			mapprograme=_context3d.createProgram();
			vertexShader=new AGALMiniAssembler();
			vertexShader.assemble(Context3DProgramType.VERTEX,vertexAgal);
			fragmentShader=new AGALMiniAssembler();
			fragmentShader.assemble(Context3DProgramType.FRAGMENT,fragmentAgal);
			mapprograme.upload(vertexShader.agalcode,fragmentShader.agalcode);
			
			_context3d.setProgram(mapprograme);
			createModel1();
		}
		
		private var maxY:Number=3,maxX:Number=5;

		protected function createTexture(texturewidth,textureHeight,bitmap:BitmapData):Texture{
			this._texture=_context3d.createTexture(texturewidth,textureHeight,Context3DTextureFormat.BGRA,false);
				 _texture.uploadFromBitmapData(bitmap);
				 return _texture;
		 }
		
		public function createModel1():void
		{
		if(_context3d)
		{
			var camera:Camera=new Camera(0,0,this.stage.stageWidth,this.stage.stageHeight);
			camera.gridWidth=350;
			camera.gridHeight=350;
			camera.maxWidth=2100;
			camera.maxHeight=2000;
			
			var px:Number=camera.gridWidth/camera.width;//x坐标比例
			var py:Number=camera.gridHeight/camera.height;//y坐标比例
			
			var puvx:Number=0.68;//camera.gridWidth/512;
			var puvy:Number=0.68;//camera.gridHeight/512;
			
			maxX=camera.xGridCount;
			var maxY:int=camera.yGridCount;
			var l:int,perdata:int;
			var vectors:Vector.<Number>=new Vector.<Number>();//顶点集合
			
			l=maxY*maxX;//模型正方形数目
			var indexs:Vector.<uint>=new Vector.<uint>();
			var col:int=0,row:int=0,tmp:int;
			for(var i:int=0;i<l;i++)
			{
				if(i % maxX ==0 && col!=0)
				{
					row++;//换行
					col=0;//新行
				}
				//画六个顶点(x,y,z					u,v);
				vectors.push(col*px,-row*py,0, 		0,0);			//0,0
				vectors.push((col+1)*px,-row*py,0, 	puvx,0);		//1,0
				vectors.push(col*px,(-row-1)*py,0, 	0,puvy);		//0,1
				
				vectors.push((col+1)*px,-row*py,0, 		puvx,0);	//1,0
				vectors.push(col*px,(-row-1)*py,0, 	0,puvy);		//0,1
				vectors.push((col+1)*px,(-row-1)*py,0, 	puvx,puvy);	//1,1
				
				tmp=i*6;
				col++;
				indexs.push(tmp,tmp+1,tmp+2,tmp+3,tmp+4,tmp+5);
			}
			
			/////////////////////////////////////// 顶点////////////////////////////
			l=vectors.length;
			perdata=5;
			vertexbuffer=_context3d.createVertexBuffer(l/perdata,perdata);
			vertexbuffer.uploadFromVector(vectors,0,l/perdata);				
			
			/////////////////////////////////////// 索引////////////////////////////
			
			l=indexs.length;
			indexbuffer=_context3d.createIndexBuffer(l);
			indexbuffer.uploadFromVector(indexs,0,l);
			
//			/////////////////////// 材质 //////////////////////
//			texture=_context3d.createTexture(512,512,Context3DTextureFormat.BGRA,true);
//			
//			texture.uploadFromBitmapData(new BitmapData(512,512,false,0xf0f0f0));
			createtexture();
			//////////////////////////矩阵//////////////////////
			finalTransform=new Matrix3D();
			model=new Matrix3D();
		}
		}
		
		public function createModel():void
		{
			var px:Number=0.3;
			var py:Number=0.6;
			var puvx:Number=350/512;
			var puvy:Number=350/512;
			
			var vectors:Vector.<Number>=new Vector.<Number>();//顶点集合
			
			var l:int;//=vectors.length;
			var perdata:int=3;
			/////////////////////////////////////// 索引////////////////////////////
			l=maxY*maxX;//模型正方形数目
			var indexs:Vector.<uint>=new Vector.<uint>();
			var col:int=0,row:int=0,tmp:int,bili:Number=0.684;
			for(var i:int=0;i<l;i++)
			{
				if(i % maxX ==0 && col!=0)
				{
					row++;//换行
					col=0;
				}

				//画六个顶点(x,y,z					u,v);
				vectors.push(col*px,row*py,0, 		0,0);			//0,0
				vectors.push((col+1)*px,row*py,0, 	puvx,0);		//1,0
				vectors.push(col*px,(row+1)*py,0, 	0,puvy);		//0,1
				
				vectors.push((col+1)*px,row*py,0, 		puvx,0);	//1,0
				vectors.push(col*px,(row+1)*py,0, 	0,puvy);		//0,1
				vectors.push((col+1)*px,(row+1)*py,0, 	puvx,puvy);	//1,1
				
				tmp=i*6;
				col++;
				indexs.push(tmp,tmp+1,tmp+2,tmp+3,tmp+4,tmp+5);
			}
			
			perdata=5;
			vertexbuffer=_context3d.createVertexBuffer(vectors.length/perdata,perdata);
			vertexbuffer.uploadFromVector(vectors,0,vectors.length/perdata);
			
			l=indexs.length;
			indexbuffer=_context3d.createIndexBuffer(l);
			indexbuffer.uploadFromVector(indexs,0,l);

			createtexture();
//			

			_camerMatrix3D=new Matrix3D();
			model.identity();
			model.appendTranslation( -1, -.5,0 ); //center cube on origin
			finalTransform=new Matrix3D();
			render();
		}
		
		private function createtexture():void
		{
			_textures=new Array();
			//			
//			var bmp:Bitmap=new tileclass1();
//			_textures.push(createTexture(texturewidth,textureHeight,bmp.bitmapData))
//			bmp=new tileclass2();
//			_textures.push(createTexture(texturewidth,textureHeight,bmp.bitmapData))
//			bmp=new tileclass3();
//			_textures.push(createTexture(texturewidth,textureHeight,bmp.bitmapData))
//			bmp=new tileclass7();
//			_textures.push(createTexture(texturewidth,textureHeight,bmp.bitmapData))
//			bmp=new tileclass8();
//			_textures.push(createTexture(texturewidth,textureHeight,bmp.bitmapData))
//			bmp=new tileclass9();
//			_textures.push(createTexture(texturewidth,textureHeight,bmp.bitmapData))
			//			
			this._texture=_context3d.createTexture(texturewidth,textureHeight,Context3DTextureFormat.BGRA,false);
//			_texture.uploadFromBitmapData(bmp.bitmapData);
		}
		
		private var texturewidth:Number=512,textureHeight:Number=512;
		public function render():void
		{
			if(_context3d)
			{
				this._context3d.clear();
				_context3d.setProgram(mapprograme);
				_context3d.setVertexBufferAt(0,vertexbuffer,0,Context3DVertexBufferFormat.FLOAT_3);
				_context3d.setVertexBufferAt(1,vertexbuffer,3,Context3DVertexBufferFormat.FLOAT_2);
				
				finalTransform.identity();
				finalTransform.append(model);
				_context3d.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX,0,finalTransform,true);
			
				var l:int=maxY*maxX*6;
				_context3d.setTextureAt(0,this._texture);
				var gx:Number=0,gy=0,gwidth:Number=4,gheight:Number=2,tmptexture:Texture;
				var key:String="",bi:int,bend:int;
				
				for(var j:int=gy;j<=gheight;j++)
				{
					for(var i:int=gx; i<=gwidth;i++)
					{
					
						tmptexture=null;
						key=i+","+j;
						bi=j*this.maxX+i;//开始正方形索引
						if(bi<_textures.length)
							tmptexture=this._textures[bi];
						if(!tmptexture)
							tmptexture=this._texture;
						_context3d.setTextureAt(0,tmptexture);
						
						_context3d.drawTriangles(indexbuffer,bi*6,2);
					}
				}	
//				_context3d.drawTriangles(indexbuffer);
//				_context3d.drawTriangles(indexbuffer,c,2);
//				for(var i:int=0;i<_textures.length;i++)
//				{
//					var text:Texture=this._textures[i];
//					_context3d.setTextureAt(0,text);
//					_context3d.drawTriangles(indexbuffer,c,2);
//					c+=6;
//					if(c==l-6)
//						c=0;
//				}
				_context3d.present();
			}
		}
		var  c:int=0,i:int=0;
		private var  view:Matrix3D=new Matrix3D(),model:Matrix3D=view.clone();//_camerMatrix3D.clone();
		private var  finalTransform:Matrix3D;
		
//		[Embed(source="images/map/dabaodong/1.jpg")]
//		public var tileclass1:Class;
//		[Embed(source="images/map/dabaodong/2.jpg")]
//		public var tileclass2:Class;
//		[Embed(source="images/map/dabaodong/3.jpg")]
//		public var tileclass3:Class;
//		
//		[Embed(source="images/map/dabaodong/7.jpg")]
//		public var tileclass7:Class;
//		[Embed(source="images/map/dabaodong/8.jpg")]
//		public var tileclass8:Class;
//		[Embed(source="images/map/dabaodong/9.jpg")]
//		public var tileclass9:Class;
		
		private const mwidth:Number=2100,mheight:Number=2000;
		//////////////////////////////私有变量///////////////////////////////////
		/////////////////////////////////////////
		//用于渲染
		////////////////////////////////////////
		private var _context3d:Context3D;
		/** 上传程序*/
		private var mapprograme:Program3D;//
		/** 顶点agal*/
		private var vertexAgal:String="m44 op, va0, vc0 \n" +    //copy position to output 
			"mov v0, va1"; //copy color to varying variable v0
		//"m44 op, va0, vc0\n" + // 顶点剪裁后位置位置 vc0
		//	"mov v0,va1 \n";//copy uv
//			"add v0, va1.xy, vc4.xy   \n" //+ // add uv offset";
		/** 片段agal*/
		private var fragmentAgal:String="tex ft0, v0, fs0 <2d,repeat,nomip>\nmov oc, ft0 \n";//"tex ft0, v0, fs0 <2d,repeat,nomip>\n" +
			//"mov oc, ft0\n";//fto
		/** 顶点着色器*/
		private var vertexShader:AGALMiniAssembler;
		/** 片段着色器*/
		private var fragmentShader:AGALMiniAssembler;
		/** 顶点集合 */
		private var vertexbuffer:VertexBuffer3D;
		/**  uv集合 */
		private var uvbuffer:VertexBuffer3D;
		/** 索引集合 */
		private var indexbuffer:IndexBuffer3D;
		/**材质 */
		private var _texture:Texture;
		private var _textures:Array;
		private var _camerMatrix3D:Matrix3D;
		private var _uvoffset:Vector.<Number>;//uv坐标偏移
	}
}